<template>
  <div class="skin-preview">
    <div class="preview-wrapper">
      <!-- 当前模型 -->
      <div class="current-model">
        <div class="preview-header">
          <h3><i class="mdi mdi-account"></i> 当前皮肤</h3>
        </div>
        <div class="preview-container">
          <div class="fixed-aspect-ratio">
            <canvas ref="viewerCanvas"></canvas>
          </div>
        </div>
        <div v-if="character" class="skin-controls">
          <div class="animation-controls">
            <button @click="toggleAnimation">
              <i class="mdi" :class="isAnimating ? 'mdi-pause' : 'mdi-play'"></i>
            </button>
            <select v-model="currentAnimationType" @change="updateAnimation">
              <option value="walk">行走</option>
              <option value="run">奔跑</option>
              <option value="idle">站立</option>
            </select>
          </div>
        </div>
      </div>

      <!-- 皮肤预览 -->
      <div class="skin-preview-model">
        <div class="preview-header">
          <h3><i class="mdi mdi-eye"></i> 皮肤预览</h3>
        </div>
        <div v-show="selectedSkinIndex >= 0" class="preview-container">
          <div class="fixed-aspect-ratio">
            <canvas ref="previewCanvas"></canvas>
          </div>
        </div>
        <div v-show="selectedSkinIndex < 0" class="preview-placeholder">
          <i class="mdi mdi-image-search"></i>
          <p>选择皮肤可以预览</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { SkinViewer, WalkingAnimation, RunningAnimation, IdleAnimation } from 'skinview3d'

const props = defineProps({
  character: {
    type: Object,
    default: null
  },
  selectedSkinIndex: {
    type: Number,
    default: -1
  },
  skinLibrary: {
    type: Array,
    default: () => []
  }
})

const viewer = ref(null)
const previewViewer = ref(null)
const viewerCanvas = ref(null)
const previewCanvas = ref(null)
const isAnimating = ref(true)
const currentAnimationType = ref('walk')
let animation = null

const initSkinViewer = () => {
  if (viewer.value)  {
    viewer.value.dispose()
    viewer.value  = null
  }

  if (previewViewer.value)  {
    previewViewer.value.dispose()
    previewViewer.value  = null
  }

  if (!props.character  || !viewerCanvas.value)  return

  // 固定画布尺寸
  const width = 300
  const height = 450

  // 初始化当前模型查看器
  viewer.value  = new SkinViewer({
    canvas: viewerCanvas.value,
    width: width,
    height: height,
    skin: `https://crafatar.com/skins/${props.character.uuid}`,
  })

  viewer.value.nameTag  = props.character.name
  viewer.value.camera.position.z  = 70
  viewer.value.zoom  = 0.7

  // 初始化预览模型查看器
  previewViewer.value  = new SkinViewer({
    canvas: previewCanvas.value,
    width: width,
    height: height,
    skin: `https://crafatar.com/skins/${props.character.uuid}`,
  })

  previewViewer.value.camera.position.z  = 70
  previewViewer.value.zoom  = 0.7

  updateAnimation()
}

// 更新动画
const updateAnimation = () => {
  if (!viewer.value)  return

  if (isAnimating.value)  {
    switch (currentAnimationType.value)  {
      case 'walk':
        animation = viewer.value.animation  = new WalkingAnimation()
        animation.speed  = 0.8
        break
      case 'run':
        animation = viewer.value.animation  = new RunningAnimation()
        animation.speed  = 0.5
        break
      case 'idle':
        animation = viewer.value.animation  = new IdleAnimation()
        break
    }
  } else {
    viewer.value.animation  = null
  }
}

// 切换动画
const toggleAnimation = () => {
  isAnimating.value  = !isAnimating.value
  updateAnimation()
}

// 监听选中的皮肤变化
watch(() => props.selectedSkinIndex,  (newIndex) => {
  if (previewViewer.value  && props.character  && newIndex >= 0) {
    previewViewer.value.skin  = `https://crafatar.com/skins/${props.skinLibrary[newIndex].uuid}`
    previewViewer.value.loadSkin(previewViewer.value.skin)
  }
})

// 监听角色变化
watch(() => props.character,  () => {
  nextTick(() => {
    initSkinViewer()
  })
}, { deep: true })

onMounted(() => {
  if (props.character)  {
    nextTick(() => {
      initSkinViewer()
    })
  }
})

onBeforeUnmount(() => {
  if (viewer.value)  viewer.value.dispose()
  if (previewViewer.value)  previewViewer.value.dispose()
})
</script>

<style scoped>
.skin-preview {
  flex: 1;
  min-width: 300px;
  background-color: #13141f;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

.preview-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}

.current-model, .skin-preview-model {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.preview-header {
  padding: 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.preview-header h3 {
  margin: 0;
  color: #4e7de4;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
}

.preview-container {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex: 1;
}

.fixed-aspect-ratio {
  position: relative;
  width: 300px;
  height: 450px;
  max-width: 100%;
  max-height: 100%;
}

.fixed-aspect-ratio canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  image-rendering: crisp-edges;
}

.skin-controls {
  padding: 16px;
  background: rgba(19, 20, 31, 0.8);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.animation-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.skin-controls button {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(78, 125, 228, 0.2);
  color: #e0e3ff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.2s;
}

.skin-controls button:hover {
  background: rgba(78, 125, 228, 0.4);
  transform: scale(1.1);
}

.skin-controls select {
  background: rgba(15, 17, 26, 0.8);
  color: #e0e3ff;
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 8px 12px;
  border-radius: 20px;
  cursor: pointer;
  font-size: 14px;
}

.preview-placeholder {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #8b93b0;
  padding: 20px;
}

.preview-placeholder i {
  font-size: 48px;
  margin-bottom: 16px;
  color: rgba(255, 255, 255, 0.2);
}

.preview-placeholder p {
  font-size: 16px;
  margin: 0;
}

@media (max-width: 1200px) {
  .skin-preview {
    width: 50%;
    order: 3;
    border-right: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  }
}

@media (max-width: 768px) {
  .skin-preview {
    width: 100%;
  }

  .fixed-aspect-ratio {
    width: 250px;
    height: 375px;
  }
}

@media (max-width: 480px) {
  .fixed-aspect-ratio {
    width: 200px;
    height: 300px;
  }
}
</style>